import torch
import torch.nn as nn
from torch.optim import SGD
import matplotlib.pyplot as plt

# print(nn.Linear(2,7))
x = [[1,2],[3,4],[5,6],[7,8]]
y = [[3],[7],[11],[15]]

X = torch.tensor(x).float()
Y = torch.tensor(y).float()

# device = 'cuda' if torch.cuda.is_available() else 'cpu'
device = 'cuda'
X = X.to(device)
Y = Y.to(device)

class MyNeuralNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.input_to_hidden_layer = nn.Linear(2,8)
        self.hidden_layer_activation = nn.ReLU()
        self.hidden_to_output_layer = nn.Linear(8,1)

    def forward(self,x):
        # x @ self.input_to_hidden_layer
        x = self.input_to_hidden_layer(x)
        x = self.hidden_layer_activation(x)
        x = self.hidden_to_output_layer(x)
        return x


mynet = MyNeuralNet().to(device)

# for par in mynet.parameters():
#     print(par)

loss_fun = nn.MSELoss()
_Y = mynet(X)
loss_value = loss_fun(_Y,Y)

opt = SGD(mynet.parameters(),lr=0.001)

loss_history = []
for _ in range(50):
    opt.zero_grad()
    _Y = mynet(X)
    loss_value = loss_fun(_Y,Y)
    loss_value.backward()
    opt.step()
    loss_history.append(loss_value.detach().cpu().numpy())

plt.figure(figsize=(10, 10))
plt.plot(loss_history)
plt.show()